package wsdc.app.main.v2;

import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 * @创建人 wsdc
 * @时间 2022/3/27
 * @描述 $
 */
@Slf4j
public class ProxyUtils {
    public static ByteArrayOutputStream readBuf(ByteBuf buf){
        ByteArrayOutputStream bos = new ByteArrayOutputStream();

        int max = buf.readableBytes();
        while(max-- > 0){
            bos.write(buf.readByte());
        }

        return bos;
    }


    public static int readBufBuffer(ByteBuf buf, Consumer<byte[]> cb){
        ByteArrayOutputStream bos = new ByteArrayOutputStream();

        int max = buf.readableBytes();
        int count = 0;
        int all = 0;
        while(max-- > 0){
            bos.write(buf.readByte());
            all++;
            //  8K
            if(count ++ > 1024 * 4){
                count = 0;
                byte[] rtn = bos.toByteArray();
                cb.accept(rtn);
                bos.reset();
            }
        }

        //  最后一页的数据
        if(count > 0){
            byte[] rtn = bos.toByteArray();
            cb.accept(rtn);
        }
        return all;
    }


    public static void write(Channel channel,ByteBuf buf){
        channel.writeAndFlush(buf);
    }

    public static void write(OutputStream os, byte[] bs){
        try{
            os.write(bs);
        } catch (IOException e) {

        }
    }

    //  map 数据源
    //  c 如果需要删除 此处回调
    //  condition 判断因子 true 或者 false
    //  func 具体的判断项目 然后根据判断因子比较 是否一致   因为我们移除的条件可能是true，也可能是false
    //  and  判断的项目 必须全部通过
    public static <K,V> void filterIfAnd(Map<K,V> map, BiConsumer<K,V> c , boolean condition, Function<V,Boolean>... func){
        List<K> removeList = new LinkedList<>();

        map.forEach((k,value) -> {
            boolean match = false;
            for (Function<V, Boolean> f : func) {
                Boolean apply = f.apply(value);
                if(Objects.equals(apply,condition)){
                    match = true;
                }else{
                    match = false;
                    break;
                }
            }

            if(match){
                removeList.add(k);
            }
        });

        //  删除key
        for (K o : removeList) {
            V remove = map.remove(o);
            if(remove != null){
                c.accept(o,remove);
            }
        }
    }

    //  只需要命中一个体检
    public static <K,V> void filterIfOr(Map<K,V> map, BiConsumer<K,V> c , boolean condition, Function<V,Boolean>... func){
        List<K> removeList = new LinkedList<>();

        map.forEach((k,value) -> {
            boolean match = false;
            for (Function<V, Boolean> f : func) {
                Boolean apply = f.apply(value);
                if(Objects.equals(apply,condition)){
                    match = true;
                    break;
                }
            }

            if(match){
                removeList.add(k);
            }
        });

        //  删除key
        for (K o : removeList) {
            V remove = map.remove(o);
            if(remove != null){
                c.accept(o,remove);
            }
        }
    }

    public static <K,V> void removeMapByList(List<K> ls,Map<K,V> map){
        for (K l : ls) {
            map.remove(l);
        }
    }

    //  此处是new为基础 old做出参照
    //  new中有 old没有 -> 新增
    //  new中有 old有   -> 修改
    //  new中没有 old有 -> 删除
    //  此处不会修改new和old的长度 即 不对里面的数据进行增删
    public static <T> void compareAddUpdateRemove(Map<? extends Serializable,T> news,Map<? extends Serializable,T> old,
                                                  CompareAddUpdateRemoveCb<T> c){
        List<T> addList = new ArrayList<>();
        List<T> updateList = new ArrayList<>();
        List<T> removeList = new ArrayList<>();

        Map<? extends Serializable,T> old1 = new HashMap<>(old);

        for (Map.Entry<? extends Serializable, T> e : news.entrySet()) {
            Serializable key = e.getKey();
            T value = e.getValue();

            T remove = old1.remove(key);

            if(remove == null){
                addList.add(value);
                c.onAdd(value);
                continue;
            }

            if(remove != null){
                updateList.add(c.onUpdate(value,remove));
                continue;
            }
        }

        for (T value : old1.values()) {
            c.onRemove(value);
            removeList.add(value);
        }

        c.finish(addList,updateList,removeList);
    }

    public interface CompareAddUpdateRemoveCb<T> {
        //  对比的过程中发现新增
        default void onAdd(T t){

        }
        //  对比的过程中发现是删除
        default void onRemove(T t){

        }
        //  对比的过程中 发现是更新 t1是新数据 t2是旧数据
        default T onUpdate(T t1,T t2){
            return t1;
        }

        //  最终的计算结果
        default void finish(List<T> addList,List<T> update,List<T> remove){

        }
    }
}
